package base

import (
	"errors"
	"fmt"
	"strconv"
	"strings"
	"time"

	//log "github.com/sirupsen/logrus"
	"github.com/tealeg/xlsx"
)

type XlsxDataReader struct {
	filePath     string
	hasColHeader bool
	workBook     *xlsx.File
}

func NewXlsxDataReader(filePath string, hasColHeader bool) (*XlsxDataReader, error) {
	book, err := xlsx.OpenFile(filePath)
	if err != nil {
		return nil, err
	}
	return &XlsxDataReader{
		filePath:     filePath,
		hasColHeader: hasColHeader,
		workBook:     book,
	}, nil
}
func (x *XlsxDataReader) GetSheetNames() ([]string, error) {
	count := len(x.workBook.Sheets)
	sheetNames := make([]string, count, count)
	for i, sheet := range x.workBook.Sheets {
		sheetNames[i] = sheet.Name
	}
	return sheetNames, nil
}
func (x *XlsxDataReader) GetDataColumns(sheetName string) ([]string, error) {
	sheet := x.workBook.Sheet[sheetName]
	errInfo := ""
	if sheet == nil {
		errInfo = fmt.Sprintf("指定的sheet[%s]不存在！", sheetName)
		return nil, errors.New(errInfo)
	}
	if sheet.MaxRow == 0 {
		errInfo = fmt.Sprintf("指定的sheet[%s]没有数据！", sheetName)
		return nil, errors.New(errInfo)
	}
	row := sheet.Rows[0]
	l := len(row.Cells)
	colNames := make([]string, l, l)
	if x.hasColHeader {
		if l == 0 {
			errInfo = fmt.Sprintf("指定的sheet[%s]首行没有数据！", sheetName)
			return nil, errors.New(errInfo)
		}
		for i, cell := range row.Cells {
			if cell.HMerge > 1 || cell.VMerge > 1 {
				errInfo = fmt.Sprintf("指定的sheet[%s]首行不允许合并单元格！", sheetName)
				return nil, errors.New(errInfo)
			}
			cName := cell.String()
			if cName == "" {
				errInfo = fmt.Sprintf("指定的sheet[%s]首行列名不能为空！", sheetName)
				return nil, errors.New(errInfo)
			}
			for _, n := range colNames {
				if n == cName {
					errInfo = fmt.Sprintf("指定的sheet[%s]首行列名[%s]不能重复！", sheetName, cName)
					return nil, errors.New(errInfo)
				}
			}
			colNames[i] = cell.String()
		}
		return colNames, nil
	} else {
		for i, cell := range row.Cells {
			if cell.HMerge > 1 || cell.VMerge > 1 {
				errInfo = fmt.Sprintf("指定的sheet[%s]首行不允许合并单元格！", sheetName)
				return nil, errors.New(errInfo)
			}
			colNames[i] = indexToColName(i)
		}
		return colNames, nil
	}
}
func (x *XlsxDataReader) ReadData(sheetName string) ([][]string, []int, error) {
	sheet := x.workBook.Sheet[sheetName]
	errInfo := ""
	if sheet == nil {
		errInfo = fmt.Sprintf("指定的sheet[%s]不存在！", sheetName)
		return nil, nil, errors.New(errInfo)
	}
	if sheet.MaxRow == 0 {
		errInfo = fmt.Sprintf("指定的sheet[%s]没有数据！", sheetName)
		return nil, nil, errors.New(errInfo)
	}
	rowlen := len(sheet.Rows)
	dataLen := rowlen
	i := 0
	k := 0
	if x.hasColHeader {
		i = 1
		dataLen--
	}
	datas := make([][]string, dataLen, dataLen)
	collen := len(sheet.Rows[0].Cells)
	blankRowIndexs := make([]int, 0, 10)
	for ; i < rowlen; i++ {
		datas[k] = make([]string, collen, collen)
		row := sheet.Rows[i]
		cLen := len(row.Cells)
		isAllBlank := true
		for j := 0; j < collen; j++ {
			cellData := ""
			if j < cLen {
				cell := row.Cells[j]
				if cell.HMerge > 1 || cell.VMerge > 1 {
					errInfo = fmt.Sprintf("指定的sheet[%s]第%d行不允许合并单元格！", sheetName, i)
					return nil, nil, errors.New(errInfo)
				}
				cellData = cell.Value
				if x.isTimeFormat(cell) {
					fData, err := strconv.ParseFloat(cellData, 64)
					if err == nil {
						cellData = xlsx.TimeFromExcelTime(fData, false).Format(time.RFC3339)
					}
				} else {
					cellData = cell.String()
				}
				if cellData != "" {
					isAllBlank = false
				}

			}
			datas[k][j] = cellData
		}
		if isAllBlank {
			blankRowIndexs = append(blankRowIndexs, k)
		}
		k++
	}
	return datas, blankRowIndexs, nil
}
func (x *XlsxDataReader) isTimeFormat(cell *xlsx.Cell) bool {
	format := cell.GetNumberFormat()
	dateParts := []string{
		"yy", "hh", "am", "pm", "ss", "mm", ":",
	}
	for _, part := range dateParts {
		if strings.Contains(format, part) {
			return true
		}
	}
	return false
}
